using System;
using System.Windows.Forms;
using CodeSnippet.Config;
using CodeSnippet.Formats;
using CodeSnippet.Helpers;
using WLWPluginBase.Win32;

namespace CodeSnippet.Forms
{
    /// <summary>
    /// Compact version of the Code Snippet form.
    /// </summary>
    internal partial class CodeSnippetCompactForm : Form, ICodeSnippetForm
    {
        #region Fields
        /// <summary>
        /// Semaphore to allow the management of the loading process.
        /// </summary>
        private readonly bool loading = true;
        #endregion Fields

        #region Properties
        /// <summary>
        /// Plugin configuration.
        /// </summary>
        /// <value>The configuration to set.</value>
        public CodeSnippetConfig Config { get; set; }
        /// <summary>
        /// Code snippet contents processed and ready for return as new content.
        /// </summary>
        public string CodeSnippet { get; private set; }
        /// <summary>
        /// Code snippet content to be processed.
        /// </summary>
        public string CodeSnippetToEdit { private get; set; }
        #endregion Properties

        #region Initialization
        /// <summary>
        /// Construct a <see cref="CodeSnippetCompactForm"/> instance with the given configuration.
        /// </summary>
        /// <param name="config">Plugin configuration.</param>
        public CodeSnippetCompactForm(CodeSnippetConfig config)
        {
            CodeSnippet = string.Empty;
            Config = config;
            InitializeComponent();
            InitializeList();
            ConfigToUI();
            loading = false;
        }
        /// <summary>
        /// Initialize the list of supported formats.
        /// </summary>
        private void InitializeList()
        {
            // Load the list of all supported formats (languages).
            lbLang.DataSource = SupportedFormat.Items;
        }
        #endregion Initialization

        #region Format Operations
        /// <summary>
        /// Transfer information from the configuration to the form's UI elements.
        /// </summary>
        private void ConfigToUI()
        {
            lbLang.SelectedItem = SupportedFormat.GetItem(Config.General.ActiveLanguage);
            btnEmbedStyles.Checked = Config.Style.EmbedStyles;
            btnUseContainer.Checked = Config.Style.UseContainer;
            btnLineNumbers.Checked = Config.Style.LineNumbers;
            btnAlternateLines.Checked = Config.Style.AlternateLines;
        }
        #endregion Format Operations

        #region Event Handlers

        #region Form Events
        /// <summary>
        /// Handles the Load event of the CodeSnippetCompactForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void CodeSnippetCompactForm_Load(object sender, EventArgs e)
        {
            if (Config.Reposition)
            {
                Win32WndHelper.SetPlacement(Handle, Config.Layout.CompactModePlacement);
            }
        }
        /// <summary>
        /// Handles the FormClosing event of the CodeSnippetCompactForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.FormClosingEventArgs"/> instance containing the event data.</param>
        private void CodeSnippetCompactForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Config.Layout.CompactModePlacement = Win32WndHelper.GetPlacement(Handle);
        }
        /// <summary>
        /// Handles the PreviewKeyDown event of the lbLang control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.PreviewKeyDownEventArgs"/> instance containing the event data.</param>
        private void lbLang_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Enter:
                    btnOK_Click(null, null);
                    break;
                case Keys.Escape:
                    btnCancel_Click(null, null);
                    break;
                case Keys.F12:
                    btnViewFullMode_Click(null, null);
                    break;
            }
        }
        /// <summary>
        /// Handles the Click event of the btnOK control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnOK_Click(object sender, EventArgs e)
        {
            CodeSnippet = FormatHelper.Format(SupportedFormat.GetItemKey(lbLang.SelectedItem),
                Config.Editor, Config.Style, string.IsNullOrEmpty(CodeSnippetToEdit) ? Clipboard.GetText()
                 : CodeSnippetToEdit, Config.Editor.TrimIndentOnPaste);
            DialogResult = DialogResult.OK;
            Close();
        }
        /// <summary>
        /// Handles the Click event of the btnCancel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }
        #endregion Form Events

        #region View Events
        /// <summary>
        /// Handles the SelectedIndexChanged event of the lbLang control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void lbLang_SelectedIndexChanged(object sender, EventArgs e)
        {
            // This check is necessary since the event will be triggered when the
            // ListBox instance detects changes to the DataSource property.
            if (!loading)
            {
                Config.General.ActiveLanguage = SupportedFormat.GetItemKey(lbLang.SelectedItem);
            }
        }
        /// <summary>
        /// Handles the Click event of the btnLineNumbers control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnLineNumbers_Click(object sender, EventArgs e)
        {
            Config.Style.LineNumbers = btnLineNumbers.Checked;
        }
        /// <summary>
        /// Handles the Click event of the btnAlternateLines control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnAlternateLines_Click(object sender, EventArgs e)
        {
            Config.Style.AlternateLines = btnAlternateLines.Checked;
        }
        /// <summary>
        /// Handles the Click event of the btnEmbedStyles control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnEmbedStyles_Click(object sender, EventArgs e)
        {
            Config.Style.EmbedStyles = btnEmbedStyles.Checked;
        }
        /// <summary>
        /// Handles the Click event of the btnUseContainer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnUseContainer_Click(object sender, EventArgs e)
        {
            Config.Style.UseContainer = btnUseContainer.Checked;
        }
        /// <summary>
        /// Handles the Click event of the btnViewFullMode control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnViewFullMode_Click(object sender, EventArgs e)
        {
            Config.General.ActiveMode = CodeSnippetViewMode.Full;
            DialogResult = DialogResult.Retry;
            Close();
        }
        #endregion View Events

        #endregion Event Handlers
    }
}